package com.hzgj.bcl.soa.registry;

import com.google.common.collect.Sets;

import com.hzgj.bcl.soa.config.ReferenceDef;
import com.hzgj.bcl.soa.config.ServiceDef;

import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import lombok.Getter;

public abstract class AbstractRegistry implements Registry {

    @Getter
    private ConcurrentMap<ReferenceDef, Set<NotifyListener>> subscribed = new ConcurrentHashMap<>();

    protected final Set<ServiceDef.Attr> registered = Sets.newConcurrentHashSet();

    @Override
    public void subscribe(NotifyListener listener, ReferenceDef... referenceDefs) {
        for (ReferenceDef s : referenceDefs) {
            subscribed.compute(s, (k, v) -> {
                if (v == null) {
                    Set<NotifyListener> vv = Sets.newHashSet();
                    vv.add(listener);
                    return vv;
                } else {
                    v.add(listener);
                    return v;
                }
            });
            registryClient(s);
            watchService(listener, s);
        }
    }

    @Override
    public void unSubscribe(ReferenceDef... referenceDefs) {
        for (ReferenceDef s : referenceDefs) {
            Set<NotifyListener> listeners = subscribed.remove(s);
            unWatchService(listeners, s);
        }
    }

    protected abstract void watchService(NotifyListener listener, ReferenceDef referenceDef);

    protected abstract void registryClient(ReferenceDef referenceDef);

    protected abstract void unWatchService(Set<NotifyListener> listeners, ReferenceDef referenceDef);
}
